package com.hcy.app.screen.relax

import android.graphics.Paint
import android.text.TextPaint

// 文本分页
object TextPaging{

    // 将文本内容分页，需要考虑屏幕宽高、字体大小、行距
    fun getPage(fullText: String, screenWidth: Int, screenHeight: Int, fontSize: Float, lineSpacing: Float): List<String>{
        val pages =mutableListOf<String>()
        val paint = Paint()
        paint.textSize = fontSize
        // 一页能显示多少行
        val maxLines = screenHeight/ (fontSize + lineSpacing)
        val maxWidth = screenWidth

        var start = 0;
        while (start < fullText.length) {
            val end = findPageEnd(fullText, start, paint,maxLines.toInt(), maxWidth );
            pages.add(fullText.substring(start, end));
            start = end;
        }

        return pages
    }


    fun getPages(fullText: String,screenWidth: Int, maxLines: Int,paint: TextPaint): List<String>{
        val pages =mutableListOf<String>()
        // 一页能显示多少行

//        val maxLines = screenHeight / Utils.getLineHeight(paint)
        val maxWidth = screenWidth

        var start = 0;
        while (start < fullText.length) {
            val end = findPageEnd(fullText, start, paint,maxLines.toInt(), maxWidth );
            pages.add(fullText.substring(start, end));
            start = end;
        }
        return pages
    }


    private fun findPageEnd(text: String,start: Int, paint: Paint,maxLines: Int,maxWidth: Int,): Int {
        var lineCount = 0
        var currentPosition = start
        var lineStart = start
        var pageEnd = start

        while (lineCount < maxLines && currentPosition < text.length) {
            // 查找下一个换行符或段落分隔符
            val nextNewLine = text.indexOf('\n',currentPosition)
            val paragraphEnd = if (nextNewLine == -1) text.length else nextNewLine + 1

            // 测量段落宽度
            val paragraph = text.substring(lineStart, paragraphEnd)
            val paragraphWidth = paint.measureText(paragraph)

            if (paragraphWidth <= maxWidth) {
                // 整段可以放在一行
                currentPosition = paragraphEnd
                pageEnd = paragraphEnd
                lineCount++
                lineStart = paragraphEnd
            }
            else {
                // 需要将段落分行
                val (breakPosition, measuredWidth) = findLineBreakPosition(text, lineStart, paragraphEnd,paint,maxWidth)

                currentPosition = breakPosition
                pageEnd = breakPosition
                lineCount++
                lineStart = breakPosition

                // 跳过换行符
                if (currentPosition < text.length && text[currentPosition] == '\n') {
                    currentPosition++
                    lineStart = currentPosition
                }

            }

            // 检查是否到达文件末尾
            if (currentPosition >= text.length) {
                break
            }
        }
        return pageEnd
    }
    // 大段段落，查找到合适的断点位置，中文可以直接切割，英文需要考虑单词的完整性
    private fun findLineBreakPosition(text: String, start: Int, end: Int,paint: Paint,maxWidth: Int): Pair<Int, Float>{
        var low = start
        var high = end
        var mid = start
        var measuredWidth = 0f

        // 使用二分查找找到合适的断点
        while ( low <high ){
            mid = (low + high) / 2
            measuredWidth = paint.measureText(text.substring(start, mid))

            when {
                measuredWidth < maxWidth -> low = mid+1
                measuredWidth > maxWidth -> high = mid - 1
                else -> return mid to measuredWidth
            }
        }

        // 确保不会在单词中间断开
        var breakPosition = mid
        while (breakPosition > start) {
            if (text[breakPosition].isWhitespace()) {
                return breakPosition to paint.measureText(text.substring(start, breakPosition))
            }
            if (breakPosition > 0 && !text[breakPosition - 1].isWhitespace()) {
                breakPosition--
            } else {
                break
            }
        }

        // 如果没有找到合适的空格，就在最大宽度处断开
        if (breakPosition == start) {
            breakPosition = mid
        }

        return breakPosition to paint.measureText(text.substring(start, breakPosition))
    }


}

